package cn.buddha.jesj.stream;

import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.StringJoiner;
import java.util.stream.Collectors;

/**
 * @ClassName StreamTest
 * @Description stream练习
 * @Version 1.0
 *
 * <pre>
 * 1- Stream(流): 是一个来自数据源的元素队列并支持聚合操作。
 *     Java中stream并不会存储元素，而是按需计算。
 *     数据源 (流的来源): 可以是集合、数组、I/O channel、产生器generator等。
 *     聚合操作: 类似sql与语句的操作，比如filter、map、reduce、match、sorted等。
 * 2- JDK8中集合接口生成流的方法:
 *      stream() -> 为集合创建串行流;
 *      parallelStream() -> 为集合创建并行流。
 * 3- 并行流
 *      将一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流。
 *      JDK8中使用Stream API可以声明性的通过 parallel() 与 sequential() 在并行流与串行流之间进行切换。
 * </pre>
 */
public class StreamTest {

    public static void main(String[] args) {
        stream();
    }

    /*
     * @Author 友野浩二
     * @Description // stream流基本方法测试
     * @Param []
     * @return void
     **/
    private static void stream() {
        System.out.println("<<<<======== 一、stream() -> 为集合创建串行流 ========>>>>");

        // 1-1 forEach: 迭代流中的每个数据
        System.out.println("1- forEach方法迭代流中的每个数据: ");
        Random randomFor = new Random();
        StringJoiner stringJoinerFor = new StringJoiner(", ", "[", "]");
        randomFor.ints().limit(10).forEach(i -> {
            stringJoinerFor.add(String.valueOf(i));
        });
        System.out.println(stringJoinerFor);

        // 1-2 map方法: 用于映射每个元素对应的结果
        System.out.println("2- map方法映射每个元素对应的结果: ");
        List<Integer> numbers = Arrays.asList(3, 2, 5, 2, 1, 6, 8);
        // 获取对应元素的平方
        List<Integer> squareList = numbers.stream().map(i -> i * i).distinct().collect(Collectors.toList());
        StringJoiner stringJoinerMap = new StringJoiner(", ", "[", "]");
        squareList.forEach(i -> {
            stringJoinerMap.add(String.valueOf(i));
        });
        System.out.println(stringJoinerMap);

        // 1-3 filter方法: 用于通过设置的条件过滤出元素
        System.out.println("3- filter方法用于通过设置的条件过滤出元素: ");
        List<String> stringList = Arrays.asList("abc", "", "def", "ghi", "jkl", "", "mn");
        // 过滤空字符串
        List<String> filtered = stringList.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
        StringJoiner stringJoinerFilter = new StringJoiner(", ", "[", "]");
        filtered.forEach(stringJoinerFilter::add);
        System.out.println(stringJoinerFilter);

        // 1-4 limit方法: 用于获取指定数量的流
        System.out.println("4- limit方法用于获取指定数量的流: ");
        Random randomLimit = new Random();
        // 打印10个随机数
        StringJoiner stringJoinerLimit = new StringJoiner(", ", "[", "]");
        randomLimit.ints().limit(10).forEach(i -> {
            stringJoinerLimit.add(String.valueOf(i));
        });

        // 1-5 sorted方法: 用于对流进行排序
        System.out.println("5- sorted方法用于对流进行排序: ");
        Random randomSorted = new Random();
        // 使用sorted方法对输出的10个随机数进行排序
        StringJoiner stringJoinerSorted = new StringJoiner(", ", "[", "]");
        randomSorted.ints().limit(10).sorted().forEach(i -> {
            stringJoinerSorted.add(String.valueOf(i));
        });
        System.out.println(stringJoinerSorted);

        System.out.println("<<<<======== 二、parallelStream() -> 为集合创建并行流 ========>>>>");

        List<String> stringParallel = Arrays.asList("abc", "", "bc", "", "efg", "dfre", "ikj");
        System.out.println(stringParallel.parallelStream().filter(String::isEmpty).count());
    }

}
